package ext.tianma.workflow;

import java.util.ArrayList;
import java.util.HashSet;

import com.ptc.mvc.builders.carambola.table.MvcTableBuilder;

import wt.doc.WTDocument;
import wt.enterprise.Master;
import wt.enterprise.RevisionControlled;
import wt.fc.PersistenceHelper;
import wt.fc.QueryResult;
import wt.fc.ReferenceFactory;
import wt.fc.WTObject;
import wt.lifecycle.LifeCycleHelper;
import wt.lifecycle.LifeCycleManaged;
import wt.lifecycle.State;
import wt.part.WTPart;
import wt.part.WTPartHelper;
import wt.part.WTPartMaster;
import wt.part.WTPartUsageLink;
import wt.query.QuerySpec;
import wt.query.SearchCondition;
import wt.util.WTException;
import wt.vc.VersionControlHelper;
import wt.workflow.engine.WfProcess;
import wt.workflow.engine.WfState;

public class DesignToMassProductionWorkFlowUtil {
    private static final String[] CURRENT_STATES_1 = { "NewProduct" };
    private static final String WORKFLOW_SAMPLE_APPROVE = "样品承认及批准流程";
    private static final String STATE_RELEASE = "MassProductionRelease";
    
    /**
     * 检查是否有关联“新品”状态的成品，且成品不是试制件（编号后缀为“-T”则为试制件）
     * 
     * @param object
     * @throws WTException
     */
    public static void checkSubmitCondition(WTObject object) throws WTException {
	if (object instanceof WTDocument) {
	    WTDocument doc = (WTDocument) object;
	    QueryResult qr = ext.com.core.CoreUtil.getAssociatedParts(doc);
	    int i = 0;
	    while (qr.hasMoreElements()) {
		Object opart = qr.nextElement();
		if (opart instanceof WTPart) {
		    WTPart part = (WTPart) opart;
		    if (part.isEndItem() && isCurrentState(part, CURRENT_STATES_1) && !part.getNumber().endsWith("-T")) {
			i++;
		    }
		}
	    }
	    if (i < 1) {
		throw new WTException("未关联\"新品\"状态的成品，且成品不是试制件");
	    }
	}
    }
    
    /**
     * 将关联的成品以及成品下所有没有关联正在运行的样品承认流程的子件设置到量产发布状态
     * 
     * @param object
     * @return
     * @throws WTException
     */
    public static ArrayList<WTPart> setPartReleasedState(WTObject object) throws WTException {
	ArrayList<WTPart> erpParts = new ArrayList<WTPart>();
	if (object instanceof WTDocument) {
	    HashSet<WTPart> allParts = new HashSet<WTPart>();
	    WTDocument doc = (WTDocument) object;
	    QueryResult qr = ext.com.core.CoreUtil.getAssociatedParts(doc);
	    while (qr.hasMoreElements()) {
		Object opart = qr.nextElement();
		if (opart instanceof WTPart) {
		    WTPart endPart = (WTPart) opart;
		    if (endPart.isEndItem()) {
			allParts.add(endPart);
			ArrayList<WTPart> subParts = new ArrayList<WTPart>();
			subParts = getAllPartChildrens(endPart);
			for (WTPart part : subParts) {
			    ArrayList<WfProcess> wfps = getAssociatedProcesse(part);
			    for (WfProcess wfp : wfps) {
				if (!wfp.getState().equals(WfState.OPEN_RUNNING) && WORKFLOW_SAMPLE_APPROVE.equals(wfp.getTemplate().getName())) {
				    allParts.add(part);
				}
			    }
			}
		    }
		}
	    }
	    erpParts.addAll(allParts);
	    setLifeCycleState(erpParts, STATE_RELEASE);
	}
	return erpParts;
    }
    
    private static boolean isCurrentState(LifeCycleManaged lcm, String[] states) {
	boolean isCurrentState = false;
	String currentState = lcm.getState().toString();
	for (String state : states) {
	    if (state.equals(currentState)) {
		isCurrentState = true;
	    }
	}
	return isCurrentState;
    }
    
    private static ArrayList<WTPart> getAllPartChildrens(WTPart parent) {
	ArrayList<WTPart> childeParts = new ArrayList<WTPart>();
	if (parent != null) {
	    try {
		QueryResult qr = WTPartHelper.service.getUsesWTPartMasters(parent);
		while (qr.hasMoreElements()) {
		    WTPartUsageLink link = (WTPartUsageLink) qr.nextElement();
		    WTPart child = (WTPart) getLatestObject((WTPartMaster) link.getUses());
		    childeParts.add(child);
		    childeParts.addAll(getAllPartChildrens(child));
		}
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	}
	return childeParts;
    }
    
    private static RevisionControlled getLatestObject(Master master) throws WTException {
	QueryResult queryResult = VersionControlHelper.service.allVersionsOf(master);
	return (RevisionControlled) queryResult.nextElement();
    }
    
    private static ArrayList<WfProcess> getAssociatedProcesse(WTObject object) throws WTException {
	ArrayList<WfProcess> wfprocesses = new ArrayList<WfProcess>();
	QueryResult qrprocesser = getAssociatedProcesses(object);
	while (qrprocesser.hasMoreElements()) {
	    Object objectprocessor = qrprocesser.nextElement();
	    wfprocesses.add((WfProcess) objectprocessor);
	}
	return wfprocesses;
    }
    
    private static QueryResult getAssociatedProcesses(WTObject object) throws WTException {
	QueryResult qr = null;
	ReferenceFactory referencefactory = new ReferenceFactory();
	String ref = referencefactory.getReferenceString(object);
	QuerySpec queryspec = new QuerySpec(WfProcess.class);
	SearchCondition sc = new SearchCondition(WfProcess.class, "businessObjReference", "=", ref);
	queryspec.appendSearchCondition(sc);
	qr = PersistenceHelper.manager.find(queryspec);
	return qr;
    }
    
    private static void setLifeCycleState(ArrayList<WTPart> reviewObjects, String toState) throws WTException {
	if (toState == null || toState.trim().length() <= 0) {
	    return;
	}
	for (WTObject review : reviewObjects) {
	    if (review instanceof LifeCycleManaged) {
		LifeCycleManaged lcm = (LifeCycleManaged) review;
		String currentlcmState = lcm.getLifeCycleState().toString();
		if (!currentlcmState.equalsIgnoreCase(toState)) {
		    LifeCycleHelper.service.setLifeCycleState(lcm, State.toState(toState));
		}
	    }
	}
	
    }
}
